﻿namespace HelenServer.Core;

public static partial class Helen
{
    public static IEnumerable<T> DepthFirstTraverse<T>(T root, Func<T, IEnumerable<T>> getChildren)
    {
        if (getChildren is null)
        {
            throw new ArgumentNullException(nameof(getChildren));
        }

        var nodeStack = new Stack<T>();

        nodeStack.Push(root);

        while (nodeStack.Count != 0)
        {
            var node = nodeStack.Pop();

            foreach (var child in getChildren(node))
            {
                nodeStack.Push(child);
            }

            yield return node;
        }
    }

    public static IEnumerable<T> BreadthFirstTraverse<T>(T root, Func<T, IEnumerable<T>> getChildren)
    {
        if (getChildren is null)
        {
            throw new ArgumentNullException(nameof(getChildren));
        }

        var nodeQueue = new Queue<T>();

        nodeQueue.Enqueue(root);

        while (nodeQueue.Count != 0)
        {
            var node = nodeQueue.Dequeue();

            foreach (var child in getChildren(node))
            {
                nodeQueue.Enqueue(child);
            }

            yield return node;
        }
    }
}